package org.luxor.commons.core.web.data;


import com.fasterxml.jackson.annotation.JsonIgnore;
import org.luxor.commons.core.exception.FeignCallException;
import org.luxor.commons.core.web.IRestStatus;
import org.luxor.commons.core.web.RestStatus;

import java.io.Serializable;

/**
 * 统一返回消息结构
 *
 * @author XinmingYan @date 2019/9/16
 */
public class R<T> implements Serializable {

    private Integer code;

    private String message;

    private T data;

    public R(int code, String message) {
        this.message = message;
        this.code = code;
    }

    public R(int code, String message, T data) {
        this.message = message;
        this.code = code;
        this.data = data;
    }

    public R(IRestStatus restStatus) {
        this.message = restStatus.message();
        this.code = restStatus.code();
    }

    public R(IRestStatus restStatus, T data) {
        this.message = restStatus.message();
        this.code = restStatus.code();
        this.data = data;
    }


    @JsonIgnore
    public boolean isSuccess() {
        return this.code == 0;
    }

    @JsonIgnore
    public R<T> assertSuccess() {
        if (isSuccess()) {
            return this;
        }
        throw new FeignCallException(String.format("(%s)%s", this.code, this.message));
    }

    @JsonIgnore
    public static <T> R<T> ok() {
        return new R(RestStatus.SUCCESS.code(), RestStatus.SUCCESS.message());
    }

    @JsonIgnore
    public static <T> R<T> ok(T data) {
        return new R(RestStatus.SUCCESS.code(), RestStatus.SUCCESS.message(), data);
    }

    @JsonIgnore
    public static <T> R<T> ok(T data, String message) {
        return new R(RestStatus.SUCCESS.code(), message, data);
    }

    @JsonIgnore
    public static <T> R<T> failed(RestStatus restStatus) {
        return new R(restStatus.code(), restStatus.message());
    }

    @JsonIgnore
    public static <T> R<T> failed(RestStatus restStatus, T data) {
        return new R(restStatus.code(), restStatus.message(), data);
    }

    @JsonIgnore
    public static <T> R<T> failed(String message) {
        return new R(RestStatus.ERROR.code(), message);
    }

    @JsonIgnore
    public static <T> R<T> failed(T data) {
        return new R(RestStatus.ERROR.code(), RestStatus.ERROR.message(), data);
    }

    @JsonIgnore
    public static <T> R<T> failed(int code, String message) {
        return new R(code, message);
    }

    @JsonIgnore
    public static <T> R<T> failed(String message, T data) {
        return new R(RestStatus.ERROR.code(), message, data);
    }


    public R() {
    }

    public Integer getCode() {
        return this.code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return this.data;
    }

    public void setData(T data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "R{" +
                "code=" + this.code +
                ", message='" + this.message + '\'' +
                ", data=" + this.data +
                '}';
    }
}
